package fgame.scene
{
	import fgame.GameState;
	import fgame.controller.Controller;
	import fgame.events.MapEvent;
	import fgame.graphic.Graphic;
	import fgame.resource.Model3DCache;
	import fgame.unit.Actor3D;
	
	import flare.collisions.RayCollision;
	import flare.collisions.SphereCollision;
	import flare.core.Camera3D;
	import flare.core.Pivot3D;
	import flare.events.MouseEvent3D;
	
	import flash.events.EventDispatcher;
	import flash.events.IEventDispatcher;
	
	import ricky.loader.MultipleLoader;
	import ricky.loader.Request;
	
	[Event(name="click", type="fgame.events.MapEvent")]
//	
	[Event(name="SceneLoaded", type="fgame.events.MapEvent")]
	
	public class SceneManager extends EventDispatcher
	{
		public function SceneManager()
		{
			_multipleLoader=MultipleLoader.instance;
			_obstacle=new Vector.<Pivot3D>();
			_floor=new Vector.<Pivot3D>();
			_actors=new Vector.<Actor3D>();
			_rayCollision=new RayCollision();
			//添加解码器
			Model3DCache.instance;
		}

		public function get camera():Camera3D
		{
			return _camera;
		}

		public function get cameraRoot():Pivot3D
		{
			return _cameraRoot;
		}

		public function get actors():Vector.<Actor3D>
		{
			return _actors;
		}

		/**
		 * 射线碰撞检测
		 */
		public function get rayCollision():RayCollision
		{
			return _rayCollision;
		}

		/**
		 * 障碍物品
		 */
		public function get obstacle():Vector.<Pivot3D>
		{
			return _obstacle;
		}

		/**
		 * 地板层
		 */
		public function get floor():Vector.<Pivot3D>
		{
			return _floor;
		}

		/** 场景对象 */
		public function get scene():Pivot3D
		{
			return _scene;
		}
		
		public function clear():void
		{
			
			for each(var f:Pivot3D in _floor)
			{
				_rayCollision.removeCollisionWith(f,false);
				f.removeEventListener(MouseEvent3D.MOUSE_DOWN,onFloorMouseDown);
			}
			
			_cameraRoot=null;
			_actors.length=0;
			_floor.length=0;
			_obstacle.length=0;
		}

		/**
		 * 加载地图
		 * @param mapURL:String 地图路径
		 * @param onComplete():Function 数据和小地图加完后调用事件
		 * @param onProgress:Function loading事件
		 */
		public function loadMap(mapURL:String,onProgress:Function=null):void
		{
			clear();
			if(_scene)
				_scene.dispose();
			_scene=null;
			
			var r:Request=new Request(mapURL,onComplete);
			_multipleLoader.loadReq([r],null,onProgress);
		}
		
		public function addActor(actor:Actor3D):void
		{
			if(_scene!=null)
			{
				_scene.addChild(Pivot3D(actor.graphic));
				_actors.push(actor);
			}
		}
		
		public function removeActor(actor:Actor3D):void
		{
			if(_scene!=null)
			{
				var g:Graphic=actor.graphic as Graphic;
				var i:int=_actors.indexOf(actor);
				if(i!=-1)
					_actors.splice(i,1);
				if(g.parent)
					g.parent.removeChild(g);
			}
		}
		
		public function remove(name:String):void
		{
			var a:Actor3D=this.getActorByName(name);
			if(a)
				this.removeActor(a);
		}
		
		
		/**
		 * 添加碰撞检测
		 */
		public function addCollisionWithObstacle(sphereCollision:SphereCollision):void
		{
			for each(var f:Pivot3D in _obstacle)
				sphereCollision.addCollisionWith(f,false);
		}
		
		/**
		 * 移除碰撞检测
		 */
		public function removeCollisionWithObstacle(sphereCollision:SphereCollision):void
		{
			for each(var f:Pivot3D in _obstacle)
				sphereCollision.removeCollisionWith(f,false);
		}
		
		//
		protected function onComplete(e:Request):void
		{
			_scene=e.data;
			_scene.name=e.key;
			_scene.parent=GameState.inst.scene;
			_scene.forEach(setupScene);
			
			for each(var f:Pivot3D in _floor)
				_rayCollision.addCollisionWith(f,false);
				
			Controller.instance.rayCollisions=_rayCollision;
			
			this.dispatchEvent(new MapEvent(MapEvent.MAP_LOADED));
		}
		
		/**
		 * 设置地毯和障碍物
		 */
		private function setupScene(e:Pivot3D):void
		{
			var name:String=e.name.toLocaleLowerCase();
//			Debug.traceMe(name,"地图构成");
			if(name=="floor")
			{
				_floor.push(e);
				e.addEventListener(MouseEvent3D.MOUSE_DOWN,onFloorMouseDown);
			}
			else if(name=="obstacle" || name=="mapcollision")
				_obstacle.push(e);
			else if(name=="cameraroot")
				_cameraRoot=e;
			else if(name=="camera")
			{
				_camera=e as Camera3D;
			}
				
		}
		
		
		private function onFloorMouseDown(e:MouseEvent3D):void
		{
			if(e.info)
			{
				var mape:MapEvent=new MapEvent(MapEvent.MOUSE_CLICK,e.bubbles,e.cancelable);
				mape.info=e.info;
				this.dispatchEvent(mape);
			}
		}
		
		/**
		 * 得到指定角色名字的控制器
		 */
		public function getActorByName(name:String):Actor3D
		{
			for each(var a:Actor3D in _actors)
			{
				if(name==a.name)
				{
					return a;
				}
			}
			
			return null;
		}
		//
		private var _camera:Camera3D;
		private var _cameraRoot:Pivot3D;
		private var _actors:Vector.<Actor3D>;
		private var _scene:Pivot3D;//场景
		private var _floor:Vector.<Pivot3D>;
		private var _obstacle:Vector.<Pivot3D>;
		private var _multipleLoader:MultipleLoader;
		private var _rayCollision:RayCollision;//=new RayCollision();
		
	}
}